/**
 * 触摸事件
 */

import { CSSProperties, ref } from "vue"

// 按钮节点信息
type ButtonRectInfo = {
  width: number
}

export default function useSwipeActionItemTouch(
  handleItemClick: () => void,
  handleCloseOther: () => void,
  setSwipeItemStatus: () => void
) {

  // 参数信息
  let propsData: {
    disabled: boolean,
    threshold: number,
    duration: number
  } = {
    disabled: false,
    threshold: 0,
    duration: 0
  }

  // 按钮节点信息
  let buttonRects: ButtonRectInfo[] = []
  // 按钮总宽度
  let buttonWidth: number = 0

  // 选项卡打开状态
  let optionsShowStatus: boolean = false

  // 内容区域样式
  let conetntSwipeStyle = ref<CSSProperties>({})
  // 按钮对应的样式
  let buttonsSwipeStyle = ref<CSSProperties[]>([])

  // 滑动标识
  let moving: boolean = false
  // 开始触摸的时间
  let touchStartTime: number = 0
  // 开始触摸时的坐标点
  let touchStartPoint: {
    x: number,
    y: number
  } = {
    x: 0,
    y: 0
  }

  // 更新参数数据
  const updatePropsData = (props: Partial<typeof propsData>) => {
    Object.assign(propsData, props)
  }

  // 更新按钮节点数据
  const updateButtonsRectData = (buttons: ButtonRectInfo[]) => {
    buttonRects = buttons || []
    buttonWidth = buttons.reduce((total, button) => {
      return total + button.width
    }, 0)
    _resetStyle()
  }

  // 更新选项卡打开状态
  const updateStatus = (status: boolean) => {
    if (propsData.disabled) return
    if (!status && optionsShowStatus) {
      _closeSwipeOptions()
    } else if (status && !optionsShowStatus) {
      _openSwipeOptions()
    }
  }

  // 开始触摸
  const touchStart = (event: TouchEvent) => {
    if (propsData.disabled) return
    // console.log('touchStart', event);
    const touches = event.touches
    // 禁止多指触控
    if (touches?.length > 1) return
    // 标识当前正在滑动中
    moving = true
    // 标记开始触摸的坐标
    touchStartPoint.x = touches[0].pageX
    touchStartPoint.y = touches[0].pageY

    // 开始触摸时间
    touchStartTime = _getCurrentTime()

    handleCloseOther()
  }

  // 触摸移动
  const touchMove = (event: TouchEvent) => {
    if (propsData.disabled || !moving) return
    // console.log('touchStart', event);
    const touches = event.touches
    const currentX = touches[0].pageX,
          currentY = touches[0].pageY;
    let moveX = currentX - touchStartPoint.x,
          moveY = currentY - touchStartPoint.y
    // 移动的X轴距离大于Y轴距离，也即终点与起点位置连线，与X轴夹角小于45度时，禁止页面滚动
    if (Math.abs(moveX) > Math.abs(moveY) || Math.abs(moveX) > propsData.threshold) {
      event.preventDefault && event.preventDefault()
      // event.stopPropagation && event.stopPropagation()
    }
    // 移动的Y轴距离大于X轴距离，也即终点与起点位置连线，与Y轴夹角小于45度时，认为页面时上下滑动而不是左右滑动单元格
    if (Math.abs(moveX) < Math.abs(moveY)) return
    
    // 限制右滑的距离，不允许内容部分往右偏移，右滑会导致X轴偏移值大于0，以此做判断
    // 此处不能直接return，因为滑动过程中会缺失某些关键点坐标，会导致错乱，所以处理的方法是在超出后设置为0
    if (optionsShowStatus) {
      // 在开启状态下，忽略左滑动
      if (moveX < 0) moveX = 0
      // 要收起菜单，最大能移动的距离为按钮的总宽度
      if (moveX > buttonWidth) moveX = buttonWidth
      // 如果是已经打开的状态，向左滑动时，移动收起菜单
      _moveSwipeOptions(-buttonWidth + moveX)
    } else {
      // 关闭状态下，忽略右滑
      if (moveX > 0) return
      // 滑动的距离不允许超过所有按钮的总宽度，此时只能左滑
      // 滑动距离设置为按钮的宽度（负数）
      if (Math.abs(moveX) > buttonWidth) moveX = -buttonWidth
      // 在滑动过程中不断移动单元格内容，使其不断显示出来
      _moveSwipeOptions(moveX)
    }
  }

  // 触摸结束
  const touchEnd = (event: TouchEvent) => {
    if (propsData.disabled || !moving) return
    // console.log('touchStart', event);
    const touches = event.changedTouches
    const currentX = touches[0].pageX,
          currentY = touches[0].pageY;
    let moveX = currentX - touchStartPoint.x
    if (optionsShowStatus) {
      // 在开启状态下，忽略左滑动
      if (moveX < 0) moveX = 0
      // 在开启状态下，点击一下内容区域，moveX为0，也即没有移动，这是执行收起操作
      if (moveX === 0) {
        setSwipeItemStatus()
        return _closeSwipeOptions()
      }
      
      // 在开启状态下，滑动距离小于阈值，则默认不关闭同时恢复原来的打开状态
      if (Math.abs(moveX) < propsData.threshold) {
        _openSwipeOptions()
      } else {
        // 如果滑动距离大于阈值则执行收起逻辑
        setSwipeItemStatus()
        _closeSwipeOptions()
      }
    } else {
      // 获取手指离开的时间
      const touchEndTime = _getCurrentTime()
      // 判断是否点击了
      if (Math.abs(currentX - touchStartPoint.x) < 5
        && Math.abs(currentY - touchStartPoint.y) < 5
        && touchEndTime - touchStartTime < 100) {
        // TODO 点击事件
        handleItemClick()
      }
      
      // 在关闭状态下，忽略右滑动
      if (moveX > 0) return
      if (Math.abs(moveX) < propsData.threshold) {
        _closeSwipeOptions()
      } else {
        setSwipeItemStatus()
        _openSwipeOptions()
      }
    }

    // 结束滑动
    moving = false
  }

  // 移动选项卡
  const _moveSwipeOptions = (moveX: number) => {
    // 设置内容的展开宽度
    conetntSwipeStyle.value = {
      transition: 'none',
      transform: `translateX(${moveX}px)`,
      '-webkit-transform': `translateX(${moveX}px)`
    }
    // 设置每个按钮对应的样式
    // 计算缩放比例
    const scaleRate = 1 - (Math.abs(moveX) / buttonWidth)
    buttonsSwipeStyle.value = buttonsSwipeStyle.value.map((style: CSSProperties, index: number) => {
      return {
        transition: 'none',
        transformOrigin: 'right center',
        transform: `translateX(${buttonRects[index].width * scaleRate}px)`,
        '-webkit-transform-origin': 'right center',
        '-webkit-transform': `translateX(${buttonRects[index].width * scaleRate}px)`
      }
    })
  }

  // 打开操作选项
  const _openSwipeOptions = () => {
    optionsShowStatus = true
    // 设置内容的展开宽度为按钮组的宽度
    conetntSwipeStyle.value = {
      transition: `transform ${propsData.duration}ms ease`,
      transform: `translateX(-${buttonWidth}px)`,
      '-webkit-transform': `translateX(-${buttonWidth}px)`
    }
    // 设置每个按钮对应的动画样式
    buttonsSwipeStyle.value = buttonsSwipeStyle.value.map((style: CSSProperties, index: number) => {
      return {
        transition: `transform ${propsData.duration}ms ease`,
        transformOrigin: 'right center',
        transform: `translateX(0px)`,
        '-webkit-transform-origin': 'right center',
        '-webkit-transform': `translateX(0px)`
      }
    })
  }

  // 关闭操作选项
  const _closeSwipeOptions = () => {
    optionsShowStatus = false
    // 设置内容的展开宽度为0
    conetntSwipeStyle.value = {
      transition: `transform ${propsData.duration}ms ease`,
      transform: `translateX(0px)`,
      '-webkit-transform': `translateX(0px)`
    }
    // 设置每个按钮对应的动画样式
    buttonsSwipeStyle.value = buttonsSwipeStyle.value.map((style: CSSProperties, index: number) => {
      return {
        transition: `transform ${propsData.duration}ms ease`,
        transformOrigin: 'right center',
        transform: `translateX(${buttonRects[index].width}px)`,
        '-webkit-transform-origin': 'right center',
        '-webkit-transform': `translateX(${buttonRects[index].width}px)`
      }
    })
  }

  // 重新创建样式
  const _resetStyle = () => {
    conetntSwipeStyle.value = {}
    buttonsSwipeStyle.value = buttonRects.map((rect) => {
      return {
        transition: 'none',
        transformOrigin: 'right center',
        transform: `translateX(${rect.width}px)`,
        '-webkit-transform-origin': 'right center',
        '-webkit-transform': `translateX(${rect.width}px)`
      }
    })
  }

  // 获取当前时间
  const _getCurrentTime = (): number => {
    return new Date().getTime()
  }

  return {
    conetntSwipeStyle,
    buttonsSwipeStyle,
    updatePropsData,
    updateButtonsRectData,
    updateStatus,
    touchStart,
    touchMove,
    touchEnd
  }
}